﻿using System.Collections.Generic;
using System.Xml;
using WMM.Tapioca.Instance;
using WMM.Tapioca.Taxonomy;
using System.Xml.Linq;
using WMM.Tapioca.Utilities;

namespace WMM.Tapioca.Instance
{
	/// <summary>
    /// XBRL 2.1 Specification 4.9
    /// Tuples have complex content and MAY contain both items and other tuples.
	/// </summary>
    public class FactTuple : Fact
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// A collection of <see cref="Fact" /> objects that are contained by the tuple.
        /// </summary>
        /// <value>
        /// The facts.
        /// </value>
		public List<Fact> Facts
		{
			get;
			set;
		}

        internal FactTuple(InstanceDocument parentInstance, XElement tupleNode, DTS dts)
            : base(parentInstance, tupleNode, dts)
        {
            this.Facts = new List<Fact>();

            foreach (XElement currentChild in tupleNode.Elements())
            {
                var currentFact = Fact.Create(parentInstance, currentChild, dts);

                if (currentFact != null)
                {
                    this.Facts.Add(currentFact);
                }
            }

            this.Concept = GetConceptFromSchema();
        }

        // 
        /// <summary>
        /// Section 4.9 of the XBRL 2.1 Specification
        /// ·  Tuple declarations in taxonomy schemas MUST NOT include a periodType or balance attribute
        ///     (See Sections 5.1.1.1 and 5.1.1.2 respectively);
        /// ·  Tuple declarations in taxonomy schemas SHOULD NOT specify local attributes, other than the 'id' attribute.
        /// </summary>
        internal void Validate()
        {
            ValidateBalance();

            foreach (XAttribute currentAttribute in this.FactElement.Attributes())
            {
                if (currentAttribute.Name.NamespaceName.Equals(Constants.XBRLI))
                {
                    log.Error("Validation error on tuple", new XbrlException("Tuples should not have attributes in XBRL spec defined namespaces."));
                    dts.ValidatedInstance = false;
                }
            }
        }

 
        private void ValidateBalance()
        {
            if (this.Concept.SchemaElement.UnhandledAttributes != null)
            {
                foreach (XmlAttribute attr in this.Concept.SchemaElement.UnhandledAttributes)
                {
                    if (attr.LocalName.Equals("balance"))
                    {
                        log.Error("Validation error on tuple", new XbrlException("Elemements where the substitutionGroup attribute value is tuple MUST NOT have a balance attribute."));
                        dts.ValidatedInstance = false;
                    }
                }
            }
        }
    }
}
